﻿using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml.Serialization;


namespace Redis.Utils
{
    /// <summary>
    /// 序列化辅助类
    /// </summary>
    public class SerializeHelper
    {

        public static long GetByteSize(object o)
        {
            BinaryFormatter bFormatter = new BinaryFormatter();
            using (MemoryStream stream = new MemoryStream())
            {
                bFormatter.Serialize(stream, o);
                return stream.Length;
            }
        }

        #region XML
        public static string SerializeToXml(object obj)
        {
            string s = "";
            using (MemoryStream ms = new MemoryStream())
            {

                try
                {
                    XmlSerializer serializer = new XmlSerializer(obj.GetType());
                    ms.Seek(0, SeekOrigin.Begin);
                    serializer.Serialize(ms, obj);
                    s = Encoding.ASCII.GetString(ms.ToArray());
                }
                catch (SerializationException e)
                {
                    Console.WriteLine("Failed to serialize. Reason: " + e.Message);
                    throw;
                }
            }
            return s;
        }
        public static object DeserializeFromXml(Type type, string s)
        {
            object o = new object();

            try
            {
                XmlSerializer serializer = new XmlSerializer(type);
                o = serializer.Deserialize(new StringReader(s));
            }
            catch (SerializationException e)
            {
                Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
                throw;
            }

            return o;
        }
        #endregion

        #region Binary

        public static byte[] SerializeToBinary(object value)
        {
            BinaryFormatter serializer = new BinaryFormatter();
            MemoryStream memStream = new MemoryStream();
            memStream.Seek(0, 0);
            serializer.Serialize(memStream, value);
            return memStream.ToArray();
        }

        public static object DeserializeFromBinary(byte[] someBytes)
        {
            IFormatter bf = new BinaryFormatter();
            object res = null;
            if (someBytes == null)
                return null;
            using (var memoryStream = new MemoryStream())
            {
                memoryStream.Write(someBytes, 0, someBytes.Length);
                memoryStream.Seek(0, 0);
                memoryStream.Position = 0;
                res = bf.Deserialize(memoryStream);
            }
            return res;

        }


        #endregion

        #region String
        public static object DeserializeFromBin(string strBase64)
        {
            object obj = null;
            IFormatter formatter = new BinaryFormatter();
            byte[] bt = System.Convert.FromBase64String(strBase64);
            using (MemoryStream ms = new MemoryStream(bt))
            {
                ms.Seek(0, SeekOrigin.Begin);//流的指针位置重新设置到0
                obj = formatter.Deserialize(ms);
                ms.Close();
            }
            return obj;
        }
        public static string SerializeToBin(object obj)
        {
            IFormatter formatter = new BinaryFormatter();
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Seek(0, SeekOrigin.Begin);
                formatter.Serialize(ms, obj);
                byte[] bt = new byte[ms.Length];
                ms.Read(bt, 0, bt.Length);
                return System.Convert.ToBase64String(bt);
            }

        }
        #endregion
    }
}